package com.gary.util;

import com.alibaba.fastjson.JSON;
import com.gary.entity.ConsulResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author peng_rui
 * @date 2022/2/21
 */
@Slf4j
@Component
public class ConsulUtil {

    @Value("${gary.consul:http://120.55.99.182:8500/v1/kv}")
    private String consulAddress;
    @Value("${gary.consul.app.prefix:/app_ip_port}")
    private String prefix;
    @Resource
    private RestTemplate restTemplate;

    /**
     *  更新/创建
     * @param key
     * @param t
     * @param <T>
     * @return
     */
    public <T> String update(String key, T t) {
        String url = consulAddress + prefix + key;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        String json = JSON.toJSONString(t);
        HttpEntity<String> entity = new HttpEntity<>(json, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, entity, String.class);
        return response.getBody();
    }

    /**
     * 根据key获取
     * @param key
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> T getValue(String key, Class<T> tClass) {
        T t = null;
        try {
            String url = consulAddress + prefix + key;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            ResponseEntity<List> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
            if (CONSTANT.SUCCESS.equals(responseEntity.getStatusCodeValue())) {
                List list = responseEntity.getBody();
                Map<String, Object> map = (Map<String, Object>) list.get(CONSTANT.FIRST);
                String encode = (String) map.get(CONSTANT.VALUE);
                String json = Base64Util.decode(encode);
                t = JSON.parseObject(json, tClass);
            }
        } catch (RestClientException e) {
            log.error("seq = {} consul获取失败, 请检查key或prefix前缀配置 ", "444", e);
        }
        return t;
    }

    /**
     * 根据key删除
     * @param key
     * @return
     */
    public String delete(String key) {
        String url = consulAddress + prefix + key;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null, String.class);
        return response.getBody();
    }

    /**
     * 获取所有的prefix前缀的 key值
     * @return
     */
    public List<String> getAllKeys() {
        List<String> body = new ArrayList<>();
        try {
            String url = consulAddress + prefix + CONSTANT.KEYS;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
            if (CONSTANT.SUCCESS.equals(response.getStatusCodeValue())) {
                body = response.getBody();
            }
        } catch (RestClientException e) {
            log.error("seq = {} consul获取所有key失败，请检查key或prefix前缀配置 ", "444", e);
        }
        return body;
    }

    /**
     * 查询所有的value
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> List<T> getAllValue(Class<T> tClass) {
        ArrayList<T> resultList = new ArrayList<>();
        try {
            String url = consulAddress + prefix + CONSTANT.VALUES;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            ResponseEntity<List> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
            if (CONSTANT.SUCCESS.equals(responseEntity.getStatusCodeValue())) {
                List list = responseEntity.getBody();
                for (Object obj : list) {
                    Map<String, Object> map = (Map<String, Object>) obj;
                    String encode = (String) map.get(CONSTANT.VALUE);
                    String json = Base64Util.decode(encode);
                    T t = JSON.parseObject(json, tClass);
                    resultList.add(t);
                }
            }
        } catch (RestClientException e) {
            log.error("seq = {} consul获取所有value失败，请检查key或prefix前缀配置 ", "444", e);
        }
        return resultList;
    }

    static class CONSTANT {
        public static final Integer FIRST = 0;
        public static final String PREFIX = "/app_ip_port";
        public static final String KEYS = "?keys";
        public static final String VALUES = "?recurse=true";
        public static final Integer SUCCESS = 200;
        public static final String VALUE = "Value";
    }
}
